package com.heima.scan.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.heima.common.exception.CustomException;
import com.heima.feign.client.ArticleFetignClient;
import com.heima.feign.client.TaskScheduleFeignClient;
import com.heima.greenScan.pojo.ScanResult;
import com.heima.greenScan.templete.BaiduAiTemplate;
import com.heima.model.article.dto.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.enums.TaskTypeEnum;
import com.heima.model.schedule.dto.TaskDto;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.entity.WmChannel;
import com.heima.model.wemedia.entity.WmNews;
import com.heima.model.wemedia.entity.WmUser;
import com.heima.scan.service.WmNewsAutoScanService;
import com.heima.utils.common.ProtostuffUtil;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.wemedia.mapper.WmChannelMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class WmNewsAutoScanServiceImpl implements WmNewsAutoScanService {

    @Resource
    private BaiduAiTemplate baiduAiTemplate;

    @Resource
    private WmNewsMapper wmNewsMapper;

    @Resource
    private WmUserMapper wmUserMapper;

    @Resource
    private WmChannelMapper wmChannelMapper;

    @Resource
    private ArticleFetignClient articleFetignClient;

    @Resource
    private TaskScheduleFeignClient taskScheduleFeignClient;


    /**
     * 文章自动审核
     * @param wmNews
     */
    @Override
    public void newAutoScan(WmNews wmNews) {
        //1.判断文章状态是否是待审核
        if(wmNews.getStatus()!=1){
            return ;
        }
        //2.抽取文章中的文本内容和图片数据
        Map<String,Object> imageAndText=extractImageAndText(wmNews);

        //敏感词审核
        String text = imageAndText.get("text").toString();

        ScanResult wordScanResult = sensitiveWordScan(text);
        if(wordScanResult.getConclusionType()!=1){
            updateWmNewsStatus(wmNews,wordScanResult);
            return ;
        }


        //3.调用百度云进行文本内容审核
        //3.1获取文本字符串

        //conclusionType: 1:合规, 2:不合规, 3:疑似, 4:审核失败
        ScanResult textScanResult = textScan(text);
        //3.2 文章审核不通过
        if(textScanResult.getConclusionType()!=1){
            //根据审核结果返回文章状态
            updateWmNewsStatus(wmNews,textScanResult);
            return ;
        }

        //4.调用百度云进行图片内容审核
        List<String> imageList = (List<String>)imageAndText.get("image");
        ScanResult imageScanResult=imageScan(imageList);

        if(imageScanResult.getConclusionType()!=1){
            updateWmNewsStatus(wmNews,imageScanResult);
            return ;
        }
        //更新数据文章状态
        //审核通过
        updateWmNewsStatus(wmNews,new ScanResult("合格",1,Collections.emptyList()));
        //发布文章到app端
//        if(wmNews.getPublishTime().getTime()<=System.currentTimeMillis()){
//            //发布文章
//            saveArticle(wmNews);
//            //修改文章状态
//            wmNews.setStatus(9);
//            //更新数据库
//            wmNewsMapper.updateById(wmNews);
//        }

        //调用任务调度服务发布任务
        wmNewsAutoPublish(wmNews.getId(),wmNews.getPublishTime());

    }


    /**
     * 文章自动发布
     * @param id
     * @param publishTime
     */
    private void wmNewsAutoPublish(Long id, Date publishTime) {
        TaskDto taskDto = new TaskDto();
        //设置任务类型
        taskDto.setTaskType(TaskTypeEnum.NEWS_SCAN_TIME.getTaskType());
        taskDto.setPriority(TaskTypeEnum.NEWS_SCAN_TIME.getPriority());
        taskDto.setExecuteTime(publishTime.getTime());

        //封装wmNews
        WmNews wmNews = new WmNews();
        wmNews.setId(id);
        //序列化
        taskDto.setParameters(ProtostuffUtil.serialize(wmNews));

        ResponseResult<Long> responseResult=taskScheduleFeignClient.addTask(taskDto);

        if(responseResult.getCode().intValue()!=200){
            throw new RuntimeException("定时发布任务保存失败");
        }

    }

    /**
     * 保存文章到app端
     * @param wmNews
     */


    /**
     * 敏感词审核
     * @param text
     * @return
     */
    private ScanResult sensitiveWordScan(String text){
//        //查询敏感词
//        List<WmSensitive> wmSensitives = wmSensitiveMapper.selectList(Wrappers.emptyWrapper());
//        //敏感词列表为空,返回审核结果
//        if(CollectionUtils.isEmpty(wmSensitives)){
//            return new ScanResult("合格",1,Collections.emptyList());
//        }
//        //初始化DFA数据结构
//        List<String> words = wmSensitives.stream().map(s -> s.getSensitives()).collect(Collectors.toList());
//        SensitiveWordUtil.initMap(words);


        //判断文本是否包含敏感词
        Map<String, Integer> result = SensitiveWordUtil.matchWords(text);
        if(CollectionUtils.isEmpty(result)){
            return new ScanResult("合格",1,Collections.emptyList());
        }

        //获取到敏感词列表,封装返回结果
        List<String> list = result.keySet().stream().collect(Collectors.toList());
        return new ScanResult("不合格",2,list);


    }

    /**
     * 调用百度ai审核图片
     * @param imageList
     * @return
     */
    private ScanResult imageScan(List<String> imageList) {

        if(imageList==null){
            return new ScanResult("合格",1,Collections.emptyList());
        }
        List<ScanResult> resultList = imageList.stream().map(image -> baiduAiTemplate.imageScan(image)).collect(Collectors.toList());
        //判断是审核通过(所有的审核结果都是1), 还是审核失败(有任何一个审核状态不是1)
        //审核通过
        if(resultList.stream().allMatch(s->s.getConclusionType()==1)){
            return new ScanResult("合格",1,Collections.emptyList());
        }
        if(resultList.stream().anyMatch(s->s.getConclusionType()==2)){
            return new ScanResult("不合规",2,Arrays.asList("图片中包含不合格信息"));
        }
        if(resultList.stream().anyMatch(s->s.getConclusionType()==3)){
            return new ScanResult("疑似",3,Arrays.asList("图片中疑似包含不合规信息"));
        }
        return new ScanResult("审核失败",4,Arrays.asList("审核失败"));
    }

    //status:0:草稿，1:提交 2:审核失败 3:人工审核 4:人工审核通过 8:审核通过(待发布) 9:已发布
    //Type: 1:合规, 2:不合规, 3:疑似, 4:审核失败
    private void updateWmNewsStatus(WmNews wmNews, ScanResult textScanResult) {
        Integer type = textScanResult.getConclusionType();
        Integer status=null;
        status=type==1?8:type==2?2:type==3?3:2;
        //更新文章状态到数据库
        wmNews.setStatus(status);
        wmNews.setReason(StringUtils.join(textScanResult.getWords(),","));
        wmNewsMapper.updateById(wmNews);
    }


    /**
     * 调用百度ai做文本审核
     * @param text
     * @return
     */
    private ScanResult textScan(String text){
        if(StringUtils.isEmpty(text)){
            return new ScanResult("合格",1,Collections.emptyList());
        }
        return baiduAiTemplate.textScan(text);
    }

    /**
     * 抽取文章内容和图片数据
     * @param wmNews
     * @return
     */
    private Map<String, Object> extractImageAndText(WmNews wmNews) {
        //文本 ： 标题，内容
        //图片： 封面， 内容
        //用于拼接文本
        StringBuilder sb = new StringBuilder();
        //用于存储素材URL
        ArrayList<String> list = new ArrayList<>();
        //拼接文章标题
        sb.append(wmNews.getTitle());
        //抽取封面图片数据
        String images = wmNews.getImages();
        if(StringUtils.isNotEmpty(images)){
            list.addAll(Arrays.asList(images.split(",")));
        }

        //抽取文章内容中的文本和图片
        List<Map> mapList = JSON.parseArray(wmNews.getContent(), Map.class);
        //如果是文本拼接字符串缓冲区
        mapList.stream().forEach(map->{
            if("text".equals(map.get("type"))){
                sb.append(map.get("value")+"@");
            }
            //如果是图片，添加到素材集合
            if("image".equals(map.get("type"))){
                list.add(map.get("value").toString());
            }
        });
        Map<String, Object> result = new HashMap<>();
        result.put("text",sb.toString());
        result.put("image",list);
        return result;
    }
}
